home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / ddj1291.zip / STAT.ZIP / SOURCE.ZIP / PAES1800.C < prev    next >
C/C++ Source or Header  |  1990-05-10  |  26KB  |  774 lines

  1. /* File:    paes1800.c
  2. **
  3. **        Copyright 1990
  4. **        Fred Motteler and Applied Microsystems Corporation
  5. **        All Rights Reserved
  6. **
  7. ** Description:    Utility functions used by the ES 1800 version of the
  8. **        statistical performance analysis package.
  9. */
  10.  
  11. #include <stdio.h>
  12. #include <dos.h>
  13. #include <fcntl.h>
  14. #include <string.h>
  15. #include <comm.h>        /* This is a Lattice specific library */
  16. #include <time.h>        /* For machine independent timeouts */
  17. #include "padef.h"
  18.  
  19. /*
  20. ** Function:    int main( argcN, argvAS )
  21. **
  22. ** Description:    ES 1800 based statistical performance analysis program.
  23. **
  24. **        Command line arguments:
  25. **
  26. **            paes1800 prog.map prog.cfg samptime cycles
  27. **
  28. **        Where:    prog.map    memory map for program
  29. **            prog.cfg    memory map configuration
  30. **            samptime    total sampling time (sec)
  31. **            cycles        bus cycles between samples
  32. */    
  33. int
  34. main( argcN, argvAS )
  35. int argcN;
  36. char *argvAS[];
  37. {
  38.     int errorN;            /* Error code */
  39.     COMPORT comN;        /* Handle to comport to use */
  40.     char comportAB[8];        /* String for comport ID, "1" or "2" */
  41.     int comportN;        /* Comport number, 1 or 2 */
  42.     char baudrateAB[12];    /* String for baudrate, "9600", "19200", etc */
  43.     long baudrateL;        /* Baudrate value, 9600, 19200, etc... */
  44.     char estypeAB[12];        /* Emulator type, "68020S", "68020U", etc... */
  45.     char runstopAB[16];        /* Emulator run/stop mode "boot_stop", etc.. */
  46.     char listAB[80];        /* Optional results listing file path/name */
  47.     char pagelinesAB[8];    /* String for number of lines/page */
  48.     int estypeN;        /* Emulator type code */
  49.     int esoperationN;        /* Emulator operation code */
  50.     int samptimeN;        /* Sampling duration in seconds */
  51.     unsigned int cyclesN;    /* Number of buss cycles between samples */
  52.     int processedN;        /* Number of map globals processed */
  53.     FILE *mapFP;        /* Map file to read */
  54.     FILE *formatFP;        /* File with map file format information */
  55.     int pagelinesN;        /* Number of lines on output page, 0 if
  56.                  * continuous, -1 if no display output, else
  57.                  * n if n lines per page. */
  58.     FILE *listFP;        /* Results output file */
  59.  
  60.     printf("paes1800 - Statistical performance analysis tool for the ES 1800\n");
  61.     printf("Version %s\n", PA_VERSION);
  62.     printf("Copyright (C) 1990  Fred Motteler and Applied Microsystems Corporation\n");
  63.     if (argcN < 5)
  64.     {
  65.     printf("Usage: paes1800 prog.map prog.cfg samptime cycles\n");
  66.     printf("    Where:  prog.map    memory map for program\n");
  67.     printf("            prog.cfg    configuration file\n");
  68.     printf("            samptime    total sampling time (sec)\n");
  69.     printf("            cycles      bus cycles between samples\n");
  70.     exit(-100);
  71.     }
  72.  
  73.     /* First open up the configuration file. */
  74.     if ((formatFP = fopen(argvAS[2], "r")) == (FILE *) NULL)
  75.     {
  76.     pa_error(PA_NO_CFG_E);
  77.     exit(PA_NO_CFG_E);
  78.     }
  79.  
  80.     /* Read in serial port, emulator, display lines, and optional output
  81.      * file configuration data from the configuration file. */
  82.     if (((errorN = paconfig(formatFP, PA_COMPORT, comportAB)) != 0) ||
  83.     ((errorN = paconfig(formatFP, PA_BAUDRATE, baudrateAB)) != 0) ||
  84.     ((errorN = paconfig(formatFP, PA_ESTYPE, estypeAB)) != 0) ||
  85.     ((errorN = paconfig(formatFP, PA_RUNSTOP, runstopAB)) != 0) ||
  86.     ((errorN = paconfig(formatFP, PA_PAGELINES, pagelinesAB)) != 0) ||
  87.     ((errorN = paconfig(formatFP, PA_LISTFILE, listAB)) != 0))
  88.     {
  89.     pa_error(errorN);
  90.     fclose(formatFP);
  91.     exit(errorN);
  92.     }
  93.  
  94.     if (((sscanf(comportAB, "%d", &comportN)) != 1) ||
  95.     ((sscanf(pagelinesAB, "%d", &pagelinesN)) != 1) ||
  96.     ((sscanf(baudrateAB, "%ld", &baudrateL)) != 1))
  97.     {
  98.     pa_error(PA_BAD_ARG_E);
  99.     fclose(formatFP);
  100.     exit(PA_BAD_ARG_E);
  101.     }
  102.  
  103.     /* Open a listing file */
  104.     if (listAB[0] == '\0')
  105.     listFP = (FILE *) NULL;
  106.     else if ((listFP = fopen(listAB, "w")) == (FILE *) NULL)
  107.     {
  108.     pa_error(PA_NO_LST_E);
  109.     fclose(formatFP);
  110.     exit(PA_NO_LST_E);
  111.     }
  112.  
  113.     /* Open a serial port */
  114.     comN = ComOpen("COM", comportN, baudrateL, 8, NO_PARITY, 1, 1024, 1, NULL);
  115.  
  116.     /* Determine the "basic" emulator type */
  117.     if (strcmp(estypeAB, "68020S") == 0)
  118.     estypeN = PA_020S;    /* 68020 (supervisor prog. fetch) */
  119.     else if (strcmp(estypeAB, "68020U") == 0)
  120.     estypeN = PA_020U;    /* 68020 (user prog. fetch) */
  121.     else if (strcmp(estypeAB, "68000S") == 0)
  122.     estypeN = PA_000S;    /* 68000 (supervisor prog. fetch) */
  123.     else if (strcmp(estypeAB, "68000U") == 0)
  124.     estypeN = PA_000U;    /* 68000 (user prog. fetch) */
  125.     else if (strcmp(estypeAB, "80X86") == 0)
  126.     estypeN = PA_80X86;    /* 80X86 */
  127.     else if (strcmp(estypeAB, "Z800X") == 0)
  128.     estypeN = PA_Z8K;    /* Z800X */
  129.     else
  130.     {
  131.     pa_error(PA_NOT_IMPL_E);
  132.     fclose(formatFP);
  133.     ComClose(comN);
  134.     return(PA_NOT_IMPL_E);
  135.     }
  136.  
  137.     /* Determine the emulator operation mode */
  138.     if (strcmp(runstopAB, "boot_stop") == 0)
  139.     esoperationN = PA_RST_RBV_STP;    /* Use ESL "RST", "RBV", "STP" */
  140.     else if (strcmp(runstopAB, "run_stop") == 0)
  141.     esoperationN = PA_RBK_STP;    /* Use ESL "RBK", "STP */
  142.     else if (strcmp(runstopAB, "run_run") == 0)
  143.     esoperationN = PA_RBK_RUN;    /* Use ESL "RBK", "RUN */
  144.     else
  145.     {
  146.     pa_error(PA_NOT_IMPL_E);
  147.     fclose(formatFP);
  148.     ComClose(comN);
  149.     return(PA_NOT_IMPL_E);
  150.     }
  151.  
  152.     /* Determine the total sample time, and the number of cycles between
  153.      * samples. */
  154.     if (((sscanf(argvAS[3], "%d", &samptimeN)) != 1) ||
  155.     ((sscanf(argvAS[4], "%d", &cyclesN)) != 1))
  156.     {
  157.     pa_error(PA_BAD_ARG_E);
  158.     fclose(formatFP);
  159.     ComClose(comN);
  160.     return(PA_BAD_ARG_E);
  161.     }
  162.  
  163.     /* Run the program and collect samples. */
  164.     if ((errorN = pa_essample(comN, estypeN, esoperationN, PA_SAMPLE,
  165.     samptimeN, cyclesN)) != 0)
  166.     {
  167.     pa_error(errorN);
  168.     fclose(formatFP);
  169.     ComClose(comN);
  170.     exit(errorN);
  171.     }
  172.  
  173.     /* Read the program's memory map and create "bins" for the program
  174.      * counter samples. */
  175.     if ((mapFP = fopen(argvAS[1], "r")) == (FILE *) NULL)
  176.     {
  177.     pa_error(PA_NO_MAP_E);
  178.     fclose(formatFP);
  179.     ComClose(comN);
  180.     exit(PA_NO_MAP_E);
  181.     }
  182.     if ((errorN = pardmap(mapFP, formatFP, 0L, &processedN)) != 0)
  183.     {
  184.     pa_error(errorN);
  185.     fclose(formatFP);
  186.     fclose(mapFP);
  187.     ComClose(comN);
  188.     exit(errorN);
  189.     }
  190.  
  191.     /* Process the samples and sort the bins according to the PC hits in
  192.      * each bin. */
  193.     printf("Processing samples\n");
  194.     if ((errorN = pa_bstuff(PA_SAMPLE, patableAHP, &processedN)) != 0)
  195.     {
  196.     pa_error(errorN);
  197.     fclose(formatFP);
  198.     fclose(mapFP);
  199.     ComClose(comN);
  200.     exit(errorN);
  201.     }
  202.  
  203.     /* Display the results and/or dump them to a file. */
  204.     padisply(patableAHP, processedN, pagelinesN, listFP);
  205.     fclose(formatFP);
  206.     fclose(mapFP);
  207.     ComClose(comN);
  208.     exit(0);
  209. }
  210.  
  211. /*
  212. ** Function:    int pa_essend(COMPORT comN, char *stringS)
  213. **
  214. ** Description:    This is a simple function that sends a string to the
  215. **        emulator and waits for a prompt responce.  "comN" is
  216. **        a port handle, returned from the Lattice "ComOpen()"
  217. **        library function.
  218. **
  219. **        If the send is successful, then a 0 is returned.  Otherwise
  220. **        an error code is returned.
  221. */
  222. int
  223. pa_essend(comN, stringS)
  224. COMPORT comN;            /* com port handle */
  225. char *stringS;            /* String to output */
  226. {
  227.     time_t t;            /* Time value for timeout delay */
  228.     int int_charN;        /* Serial port character */
  229.  
  230.     t = time(NULL);        /* Get starting time. */
  231.  
  232.     /* Send the string and wait until either a prompt is returned, or a
  233.      * time out occurs. */
  234.     ComPuts(comN, stringS);
  235.     while((int_charN = ComGetc(comN)) != ((int) '>'))
  236.     {
  237.     if ((pa_debugN & PA_SER_IN) != 0)
  238.         putchar(int_charN);    
  239.     if ((time(NULL) - t) > PA_TIMEOUT)
  240.         return(PA_ES_NORESP_E);
  241.     }
  242.     return(0);
  243. }
  244.  
  245. /*
  246. ** Function:    int pa_estup(COMPORT comN, char *tupfileS)
  247. **
  248. ** Description:    This is a simple function that sends the "TUP 0 TO #2045"
  249. **        command to a ES 1800 68020 emulator.  The address values are
  250. **        determined from the response, and are written to the binary
  251. **        file named by tupfileP.
  252. **
  253. **        If the TUP command is successful, then a 0 is returned.
  254. **        Otherwise an error code is returned.
  255. */
  256. int
  257. pa_estup(comN, tupfileS)
  258. COMPORT comN;            /* com port handle */
  259. char *tupfileS;            /* File to write TUP data to */
  260. {
  261.     time_t t;            /* Time value for timeout delay */
  262.     int int_charN;        /* Serial port character */
  263.     int handleN;        /* File handle for tup data */
  264.     unsigned long addressL;    /* Address from tup command */
  265.     int digit_countN;        /* Digit count in tup response line */
  266.  
  267.     t = time(NULL);        /* Get starting time */
  268.  
  269.    if ((handleN = open(tupfileS, (O_CREAT | O_WRONLY | O_RAW), 0)) == (-1))
  270.     return(PA_NO_TUP_FILE_E);
  271.  
  272.    /* Send the TUP command. */
  273.     ComPuts(comN, "TUP 0 TO #2045\r");
  274.  
  275.     /* Wait for the first colon character from the TUP command */
  276.     while((int_charN = ComGetc(comN)) != ((int) ':'))
  277.     {
  278.     if ((pa_debugN & PA_SER_IN) != 0)
  279.         putchar(int_charN);    
  280.     if ((time(NULL) - t) > PA_TIMEOUT)
  281.     {
  282.         close(handleN);
  283.         return(PA_ES_NORESP_E);
  284.     }
  285.     }
  286.  
  287.     /* We have the first colon, continue reading until we get an ESL
  288.      * prompt.  As we read each trace buffer record (one bus cycle per
  289.      * record), the address value is extraced. The result is then written
  290.      * to a binary file. */
  291.     addressL = 0L;
  292.     digit_countN = 0;
  293.     while((int_charN = ComGetc(comN)) != ((int) '>'))
  294.     {
  295.     /* Check if the input queue is temporarily empty.  If so, then try
  296.      * again... */
  297.     if (int_charN == (-1))
  298.         continue;
  299.     if ((pa_debugN & PA_SER_IN) != 0)
  300.         putchar(int_charN);    
  301.     if (int_charN == ':')
  302.     {
  303.         /* Write out the address value.  The byte order of the value
  304.          * written out is host dependent.  Thus it must be read in the
  305.          * same way. */
  306.         if (write(handleN, ((char *) &addressL), sizeof(addressL)) !=
  307.         sizeof(addressL))
  308.         {
  309.         close(handleN);
  310.         return(PA_NO_TUP_WR_E);
  311.         }
  312.  
  313.         /* Re-initialize address and digit count values for next
  314.          * record. */
  315.         addressL = 0L;
  316.         digit_countN = 0;
  317.     }
  318.     else if (isxdigit(int_charN))
  319.     {
  320.         /* Collect the proper address digits */
  321.         if (digit_countN++ < 6)
  322.         {
  323.             /* Hex digits 0 through 5 are the low 24 bits of address. */
  324.         addressL <<= 4;
  325.         addressL += pa_hextobin(int_charN);
  326.         }
  327.         else if (digit_countN == 11)
  328.         {
  329.         /* Hex digits 10 and 11 are the high 8 bits of the address.
  330.          * Note that the digit count has already been incremented,
  331.          * so the comparison values are one greater than the digit
  332.          * values.  First read the ms digit. */
  333.         addressL += (((unsigned long) pa_hextobin(int_charN)) << 28);
  334.         }
  335.         else if (digit_countN == 12)
  336.         {
  337.         /* Then read the ls digit. */
  338.         addressL += (((unsigned long) pa_hextobin(int_charN)) << 24);
  339.         }
  340.     }
  341.     }
  342.     /* Write out the last address value.  The byte order of the value written
  343.      * out is host dependent.  Thus it must be read in the same way. */
  344.     if (write(handleN, ((char *) &addressL), sizeof(addressL)) !=
  345.     sizeof(addressL))
  346.     return(PA_NO_TUP_WR_E);
  347.     close(handleN);
  348.     return(0);
  349. }
  350.  
  351. /*
  352. ** Function:    int pa_esdrt(COMPORT comN, char *drtfileS)
  353. **
  354. ** Description:    This is a simple function that sends the "DRT 0 TO #2045"
  355. **        command to a ES 1800 emulator.  The address values are
  356. **        determined from the response, and are written to the binary
  357. **        file named by drtfileP.
  358. **
  359. **        The basic DRT format looked for is:
  360. **
  361. **        #line_count  addresss  ...other stuff...
  362. **
  363. **        Lines with
  364. **
  365. **        #line_count BREAK
  366. **
  367. **        are ignored.
  368. **
  369. **        If the DRT command is successful, then a 0 is returned.
  370. **        Otherwise an error code is returned.
  371. */
  372. int
  373. pa_esdrt(comN, drtfileS)
  374. COMPORT comN;            /* com port handle */
  375. char *drtfileS;            /* File to write DRT data to */
  376. {
  377.     time_t t;            /* Time value for timeout delay */
  378.     int int_charN;        /* Serial port character */
  379.     int handleN;        /* File handle for drt data */
  380.     unsigned long addressL;    /* Address from drt command */
  381.     int digit_countN;        /* Digit count in drt response line */
  382.     char responseAB[256];    /* DRT resp line - may be several lines */
  383.     int line_countN;        /* Line count value of DRT response line */
  384.     int i;            /* Index to count '#' characters */
  385.  
  386.     t = time(NULL);        /* Get starting time */
  387.     line_countN = 2045;        /* Initialize to maximum trace line count */
  388.  
  389.    if ((handleN = open(drtfileS, (O_CREAT | O_WRONLY | O_RAW), 0)) == (-1))
  390.     return(PA_NO_DRT_FILE_E);
  391.  
  392.    /* Send the DRT command. */
  393.     ComPuts(comN, "DRT 0 TO #2045\r");
  394.  
  395.     /* Wait for the first two '#' characters from the DRT command response.
  396.      * The first is in the DRT command, the second is the first line of
  397.      * trace memory. */
  398.     for (i = 0; i < 2; i++)
  399.     {
  400.     while((int_charN = ComGetc(comN)) != ((int) '#'))
  401.     {
  402.         if ((pa_debugN & PA_SER_IN) != 0)
  403.         putchar(int_charN);    
  404.         if ((time(NULL) - t) > PA_TIMEOUT)
  405.         {
  406.         close(handleN);
  407.         return(PA_ES_NORESP_E);
  408.         }
  409.     }
  410.     }
  411.  
  412.     /* We have the first '#' character, continue reading until the line
  413.      * count value of 1 is reached.  */
  414.     digit_countN = 0;        /* Start "lines" just after '#' character */
  415.     while (line_countN != 1)
  416.     {
  417.     /* Read in a character.  If the input queue is empty, then continue
  418.      * trying. */
  419.     while((int_charN = ComGetc(comN)) == (-1));
  420.     if ((pa_debugN & PA_SER_IN) != 0)
  421.         putchar(int_charN);    
  422.     if (int_charN != '#')
  423.     {
  424.         /* Collect the characters of the line */
  425.         responseAB[digit_countN] = int_charN;
  426.         digit_countN++;
  427.         if ((digit_countN < 0) || (digit_countN > 255))
  428.         {
  429.         close(handleN);
  430.         return(PA_DCOUNT_OUT_E);
  431.         }
  432.     }
  433.     else
  434.     {
  435.         /* We have a '#' character, process the input line.
  436.          * First Nul terminate the line. */
  437.         responseAB[digit_countN] = '\0';
  438.  
  439.         /* Check if the line contains "BREAK", if so, then skip it. */
  440.         if (pa_strsrch(responseAB, "BREAK") == 0)
  441.         {
  442.         /* Line does not contain a "BREAK", read in its line number
  443.          * and the address value. */
  444.         if (sscanf(responseAB, "%d %lx", &line_countN, &addressL) != 2)
  445.         {
  446.             close(handleN);
  447.             return(PA_BAD_DRT_RD_E);
  448.         }
  449.         if ((line_countN < 0) || (line_countN > 2045))
  450.         {
  451.             close(handleN);
  452.             return(PA_LCOUNT_OUT_E);
  453.         }
  454.  
  455.         /* Write out the address value.  The byte order of the value
  456.          * written out is host dependent.  Thus it must be read in the
  457.          * same way. */
  458.         if (write(handleN, ((char *) &addressL), sizeof(addressL)) !=
  459.             sizeof(addressL))
  460.         {
  461.             close(handleN);
  462.             return(PA_NO_DRT_WR_E);
  463.         }
  464.         }
  465.  
  466.         /* Re-initialize digit count values for next record. */
  467.         digit_countN = 0;
  468.     }
  469.     }
  470.     /* Here the last line will contain "#0 BREAK" and thus does not need
  471.      * to be processed, but we do need to continue reading until we get
  472.      * an ESL prompt. */
  473.     while((int_charN = ComGetc(comN)) != ((int) '>'));
  474.     printf("\n");
  475.     close(handleN);
  476.     return(0);
  477. }
  478.  
  479. /*
  480. ** Function:    int pa_essample(COMPORT comN, int estypeN,
  481. **                int esoperationN, char *sampfileS,
  482. **                int samptimeN, unsigned int cyclesN);
  483. **
  484. ** Description: This function controls an ES 1800 emulator to sample
  485. **        instruction fetch cycles from a target system.  Note that
  486. **        any previous event monitor configuration is overwritten
  487. **        by the event monitor configuration required to support
  488. **        instruction fetch sampling.
  489. **
  490. **        The comN handle selects the serial port that the ES 1800
  491. **        is connected to.
  492. **
  493. **        "Basic" Emulator types currently supported:
  494. **        estypeN =
  495. **            PA_020S        68020 (supervisor program instr. fetch)
  496. **            PA_020U        68020 (user program instr. fetch)
  497. **                    (The ES 1800 68020 emulator must be
  498. **                    configured to use its "COMPUTER PORT"
  499. **                    in order to use the faster "TUP"
  500. **                    command to upload trace    memory.)
  501. **            PA_000S        6800x/010/302 (sup. prog. instr. fetch)
  502. **            PA_000U        6800x/010/302 (user prog. instr. fetch)
  503. **            PA_80X86    80x86 (808x,8018x,80C18x,80286)
  504. **            PA_Z8K        Z800x
  505. **
  506. **        Emulator operations supported:
  507. **        esoperationN =
  508. **            PA_RST_RBV_STP    Reset the target, load program counter
  509. **                    from vector table, and start program
  510. **                    execution.  The target will be halted
  511. **                    after the sample period.
  512. **                    ("RST", "RBV", then "STP")
  513. **
  514. **            PA_RBK_STP    Run from current configuration.  The
  515. **                    target is assumed to initially be
  516. **                    halted, and will be halted after the
  517. **                    sampling period.
  518. **                    ("RBK",  then "STP")
  519. **
  520. **            PA_RBK_RUN    Run from current configuration.  The
  521. **                    target is assumed to be running.
  522. **                    The "RBK" command enables the event
  523. **                    monitor to trace cycles and a "RUN"
  524. **                    disables the event monitor.
  525. **
  526. **        sampfileS points to the string that gives the file to write
  527. **        the binary format instruction fetch address cycles to.
  528. **
  529. **        samptimeN gives the number of seconds to sample instruction
  530. **        fetch cycles from the target system.  If the ES 1800's trace
  531. **        buffer is overrun, then the trace buffer acts as a circular
  532. **        buffer that tracks the most recent 2045 instruction fetch
  533. **        samples.
  534. **
  535. **        cyclesN gives the number of bus cycles to allow between
  536. **        instruction fetch samples. (0 to 65536)
  537. **
  538. */
  539. int
  540. pa_essample(comN, estypeN, esoperationN, sampfileS, samptimeN, cyclesN)
  541. COMPORT comN;            /* Handle to comport to use */
  542. int estypeN;            /* Emulator type code */
  543. int esoperationN;        /* Emulator operation code */
  544. char *sampfileS;        /* Pntr to name of file to write samples to */
  545. int samptimeN;            /* Sampling duration in seconds */
  546. unsigned int cyclesN;        /* Number of buss cycles between samples */
  547. {
  548.     time_t t;            /* For recording run start time */
  549.     int errcodeN;        /* Error code */
  550.     char stagebufAC[32];    /* Staging buffer for ESL commands */
  551.  
  552.     /* Clear current event monitor configuration */
  553.     if ((errcodeN = pa_essend(comN, "CES\r")) != 0)
  554.     return(errcodeN);
  555.  
  556.     /* Configure the event monitor system.  This depends on the type of
  557.      * emulator being used. */
  558.     printf("Configuring the Event Monitor system\n");
  559.     switch(estypeN)
  560.     {
  561.       case PA_020S:
  562.       case PA_020U:
  563.     /* 68020 emulator, assume trace mode 2, 32 bit address, 32 bit data,
  564.      * limited status.  In this case, AC1 and S1 are used as a 32 bit
  565.      * address comparator.  S2 is used to limit traced bus cycles to
  566.      * supervisory program or user program. */
  567.  
  568.     /* Send the event monitor configuration. */
  569.     if ((errcodeN = pa_essend(comN, "WHEN AC1 AND S1 THEN CNT\r")) != 0)
  570.         return(errcodeN);
  571.     if ((errcodeN = pa_essend(comN, "WHEN CL AND S2 THEN TRC,RCT\r")) != 0)
  572.         return(errcodeN);
  573.  
  574.     /* Send the values of the address comparator registers. */
  575.     if ((errcodeN = pa_essend(comN, "AC1=0 TO $FFFFFF\r")) != 0)
  576.         return(errcodeN);
  577.     if ((errcodeN = pa_essend(comN, "S1=0 DC $FFFF\r")) != 0)
  578.         return(errcodeN);
  579.  
  580.     /* Send the value of the number of buss cycles between traced cycles */
  581.     strcpy(stagebufAC, "CL=$");
  582.     sprintf(&(stagebufAC[4]), "%x\r", cyclesN);
  583.     if ((errcodeN = pa_essend(comN, stagebufAC)) != 0)
  584.         return(errcodeN);
  585.  
  586.     /* Send the value of the buss cycle type to trace */
  587.     if (estypeN == PA_020S)
  588.     {
  589.         strcpy(stagebufAC, "S2=SP\r");    /* Trace supervisor program */ 
  590.         printf("Configured to trace 68020 Supervisor Program fetch cycles\n");
  591.     }
  592.     else
  593.     {
  594.         strcpy(stagebufAC, "S2=UP\r");    /* Trace user program */
  595.         printf("Configured to trace 68020 User Program fetch cycles\n");
  596.     }
  597.     if ((errcodeN = pa_essend(comN, stagebufAC)) != 0)
  598.         return(errcodeN);
  599.     break;
  600.       case PA_000S:
  601.       case PA_000U:
  602.     /* 68000 class emulator, assume 24 bit address, 8/16 bit data,
  603.      * full status. AC1 is used as an address comparator.  S1 is used to
  604.      * limit traced bus cycles to supervisory program or user program. */
  605.     /* Send the event monitor configuration. */
  606.     if ((errcodeN = pa_essend(comN, "WHEN AC1 THEN CNT\r")) != 0)
  607.         return(errcodeN);
  608.     if ((errcodeN = pa_essend(comN, "WHEN CL AND S1 THEN TRC,RCT\r")) != 0)
  609.         return(errcodeN);
  610.  
  611.     /* Send the values of the address comparator registers. */
  612.     if ((errcodeN = pa_essend(comN, "AC1=0 TO $FFFFFF\r")) != 0)
  613.         return(errcodeN);
  614.  
  615.     /* Send the value of the number of buss cycles between traced cycles */
  616.     strcpy(stagebufAC, "CL=$");
  617.     sprintf(&(stagebufAC[4]), "%x\r", cyclesN);
  618.     if ((errcodeN = pa_essend(comN, stagebufAC)) != 0)
  619.         return(errcodeN);
  620.  
  621.     /* Send the value of the buss cycle type to trace */
  622.     if (estypeN == PA_000S)
  623.     {
  624.         strcpy(stagebufAC, "S1=SP\r");    /* Trace supervisor program */ 
  625.         printf("Configured to trace 68000 Supervisor Program fetch cycles\n");
  626.     }
  627.     else
  628.     {
  629.         strcpy(stagebufAC, "S1=UP\r");    /* Trace user program */
  630.         printf("Configured to trace 68000 User Program fetch cycles\n");
  631.     }
  632.     if ((errcodeN = pa_essend(comN, stagebufAC)) != 0)
  633.         return(errcodeN);
  634.     break;
  635.       case PA_80X86:
  636.     /* 80x86 class emulator, assume 24 bit address, 8/16 bit data,
  637.      * full status. AC1 is used as an address comparator.  S1 is used to
  638.      * limit traced bus cycles to instruction fetch. */
  639.     /* Send the event monitor configuration. */
  640.     if ((errcodeN = pa_essend(comN, "WHEN AC1 THEN CNT\r")) != 0)
  641.         return(errcodeN);
  642.     if ((errcodeN = pa_essend(comN, "WHEN CTL AND S1 THEN TRC,RCT\r")) != 0)
  643.         return(errcodeN);
  644.  
  645.     /* Send the values of the address comparator registers. */
  646.     if ((errcodeN = pa_essend(comN, "AC1=0 TO $FFFFFF\r")) != 0)
  647.         return(errcodeN);
  648.  
  649.     /* Send the value of the number of buss cycles between traced cycles */
  650.     printf("Configured to trace 80X86 instruction fetch cycles\n");
  651.     strcpy(stagebufAC, "CTL=$");
  652.     sprintf(&(stagebufAC[5]), "%x\r", cyclesN);
  653.     if ((errcodeN = pa_essend(comN, stagebufAC)) != 0)
  654.         return(errcodeN);
  655.  
  656.     /* Send the value S1 to the trace only instruction fetch cycles */
  657.     if ((errcodeN = pa_essend(comN, "S1=IF\r")) != 0)
  658.         return(errcodeN);
  659.     break;
  660.       case PA_Z8K:
  661.     /* Z800x class emulator, assume 24 bit address, 8/16 bit data,
  662.      * full status. A1 is used as an address comparator.  S1 is used to
  663.      * limit traced bus cycles to instruction fetch. */
  664.     /* Send the event monitor configuration. */
  665.     if ((errcodeN = pa_essend(comN, "WHEN A1 THEN CNT\r")) != 0)
  666.         return(errcodeN);
  667.     if ((errcodeN = pa_essend(comN, "WHEN CL AND S1 THEN TRC,RCT\r")) != 0)
  668.         return(errcodeN);
  669.  
  670.     /* Send the values of the address comparator registers. */
  671.     if ((errcodeN = pa_essend(comN, "A1=0 TO $FFFFFF\r")) != 0)
  672.         return(errcodeN);
  673.  
  674.     /* Send the value of the number of buss cycles between traced cycles */
  675.     printf("Configured to trace Z800X instruction fetch cycles\n");
  676.     strcpy(stagebufAC, "CL=$");
  677.     sprintf(&(stagebufAC[4]), "%x\r", cyclesN);
  678.     if ((errcodeN = pa_essend(comN, stagebufAC)) != 0)
  679.         return(errcodeN);
  680.  
  681.     /* Send the value S1 to the trace only first instruction fetch
  682.      * cycles */
  683.     if ((errcodeN = pa_essend(comN, "S1=INS1\r")) != 0)
  684.         return(errcodeN);
  685.     break;
  686.       default:
  687.         /* Other types not currently supported */
  688.     return(PA_NOT_IMPL_E);
  689.     }
  690.  
  691.     /* Start sampling.  This depends on the initial state of the emulator. */
  692.     printf("Starting sampling\n");
  693.     /* Synchronize time to have consistant time intervals. */
  694.     t = time(NULL);        /* Get initial starting time. */
  695.     while (time(NULL) == t);    /* Wait for second transition */
  696.     switch(esoperationN)
  697.     {
  698.       case PA_RST_RBV_STP:
  699.     /* Reset the target, load program counter/stack pointer from
  700.      * the target system's reset vectors, and start the target program
  701.      * running. */
  702.     if ((errcodeN = pa_essend(comN, "RST\r")) != 0)
  703.         return(errcodeN);
  704.     if ((errcodeN = pa_essend(comN, "RBV\r")) != 0)
  705.         return(errcodeN);
  706.     printf("RST / RBV start up sequence\n");
  707.     break;
  708.       case PA_RBK_STP:
  709.      /* Run from the current configuration.  The target system is assumed
  710.       * to be stopped, but is all set up to run. */
  711.     if ((errcodeN = pa_essend(comN, "RBK\r")) != 0)
  712.         return(errcodeN);
  713.     printf("RBK start up sequence\n");
  714.     break;
  715.       case PA_RBK_RUN:
  716.      /* Run from the current configuration.  The target system is assumed
  717.       * to be running */
  718.     if ((errcodeN = pa_essend(comN, "OFF TCE\r")) != 0)
  719.         return(errcodeN);
  720.     if ((errcodeN = pa_essend(comN, "RBK\r")) != 0)
  721.         return(errcodeN);
  722.     if ((errcodeN = pa_essend(comN, "ON TCE\r")) != 0)
  723.         return(errcodeN);
  724.     printf("OFF TCE / RBK / ON TCE start up sequence\n");
  725.     break;
  726.       default:
  727.         /* Other modes not currently supported */
  728.     return(PA_NOT_IMPL_E);
  729.     }
  730.  
  731.     /* Wait a bit for the target to run. */
  732.     t = time(NULL);        /* Get new starting time. */
  733.     while ((time(NULL) - t) < samptimeN);
  734.  
  735.     /* Stop sampling.  This depends on the desired final state of the
  736.      * emulator. */
  737.     printf("Stopping sampling\n");
  738.     switch(esoperationN)
  739.     {
  740.       case PA_RST_RBV_STP:
  741.       case PA_RBK_STP:
  742.     /* Stop the target system. */
  743.     if ((errcodeN = pa_essend(comN, "STP\r")) != 0)
  744.         return(errcodeN);
  745.     printf("STP stop sequence\n");
  746.     break;
  747.       case PA_RBK_RUN:
  748.     /* Stop trace capture, keep the target system running. */
  749.     if ((errcodeN = pa_essend(comN, "OFF TCE\r")) != 0)
  750.         return(errcodeN);
  751.     if ((errcodeN = pa_essend(comN, "RUN\r")) != 0)
  752.         return(errcodeN);
  753.     printf("OFF TCE / RUN stop sequence\n");
  754.     break;
  755.       default:
  756.         /* Other modes not currently supported */
  757.     return(PA_NOT_IMPL_E);
  758.     }
  759.  
  760.     /* Upload trace memory.  How this is done depends on the type of
  761.      * emulator being used. */
  762.     printf("Uploading trace memory, please wait...\n");
  763.     switch(estypeN)
  764.     {
  765.       case PA_020S:
  766.       case PA_020U:
  767.     return(pa_estup(comN, sampfileS));
  768.       default:
  769.     return(pa_esdrt(comN, sampfileS));
  770.     }
  771. }
  772.  
  773.  
  774.